#ifndef DOCUMENTOBJECTMOCK_H
#define DOCUMENTOBJECTMOCK_H

#include "LeDocumentObject/IDocumentObject.h"

#include <QString>
#include <QStringList>
#include <QPointF>
#include <QSizeF>

class DocumentObjectMock0 : public LDO::IDocumentObject
{
    Q_OBJECT

public:
    enum
    {
        Type = MockBaseType + 0
    };

    Q_INVOKABLE explicit DocumentObjectMock0();

    // IDocumentObject interface
public:
    virtual int objectType() const override { return Type; }
};
Q_DECLARE_METATYPE(DocumentObjectMock0*)

class DocumentObjectMock1 : public LDO::IDocumentObject
{
    Q_OBJECT

    Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged)
    Q_PROPERTY(qreal real READ real WRITE setReal NOTIFY realChanged)
    Q_PROPERTY(int integer READ integer WRITE setInteger NOTIFY integerChanged)
    Q_PROPERTY(DocumentObjectMock1::MockEnum enumeration READ enumeration WRITE setEnumeration NOTIFY enumerationChanged)
    Q_PROPERTY(DocumentObjectMock1::MockFlags flags READ flags WRITE setFlags NOTIFY flagsChanged)
    Q_PROPERTY(QStringList stringList READ stringList WRITE setStringList NOTIFY stringListChanged)

public:
    enum
    {
        Type = MockBaseType + 1
    };

    enum MockEnum
    {
        MockEnum3 = 0,
        MockEnum1,
        MockEnum4,
        MockEnum8
    };
    Q_ENUM(MockEnum)

    enum MockFlag
    {
        MockFlag1 = 0x01,
        MockFlag2 = 0x02,
        MockFlag3 = 0x04,
    };
    Q_DECLARE_FLAGS(MockFlags, MockFlag)
    Q_FLAG(MockFlags)

    Q_INVOKABLE explicit DocumentObjectMock1();

    QString string() const;
    qreal real() const;
    int integer() const;
    MockEnum enumeration() const;
    MockFlags flags() const;
    QStringList stringList() const;

public slots:
    void setString(QString string);
    void setReal(qreal real);
    void setInteger(int integer);
    void setEnumeration(MockEnum enumeration);
    void setFlags(MockFlags flags);
    void setStringList(QStringList stringList);

signals:
    void stringChanged(QString string);
    void realChanged(qreal real);
    void integerChanged(int integer);
    void enumerationChanged(MockEnum enumeration);
    void flagsChanged(MockFlags flags);
    void stringListChanged(QStringList stringList);

private:
    QString m_string;
    qreal m_real = 0.0;
    int m_integer = 0;
    MockEnum m_enumeration = MockEnum3;
    MockFlags m_flags = 0;
    QStringList m_stringList;

    // IDocumentObject interface
public:
    virtual int objectType() const override;
};

Q_DECLARE_OPERATORS_FOR_FLAGS(DocumentObjectMock1::MockFlags)
Q_DECLARE_METATYPE(DocumentObjectMock1*)

class DocumentObjectMock2 : public LDO::IDocumentObject
{
    Q_OBJECT
    Q_PROPERTY(DocumentObjectMock1* object READ object WRITE setObject NOTIFY objectChanged)

public:
    enum
    {
        Type = MockBaseType + 2
    };

    Q_INVOKABLE explicit DocumentObjectMock2();

    DocumentObjectMock1 *object() const;

public slots:
    void setObject(DocumentObjectMock1 *object);

signals:
    void objectChanged(DocumentObjectMock1* object);

private:
    DocumentObjectMock1* m_object = nullptr;

    // IDocumentObject interface
public:
    virtual int objectType() const override { return Type; }
};
Q_DECLARE_METATYPE(DocumentObjectMock2*)

class DocumentObjectMock3 : public LDO::IDocumentObject
{
    Q_OBJECT
    Q_PROPERTY(QList<DocumentObjectMock1*> objects READ objects WRITE setObjects NOTIFY objectsChanged)

public:
    enum
    {
        Type = MockBaseType + 3
    };

    Q_INVOKABLE explicit DocumentObjectMock3();

    QList<DocumentObjectMock1 *> objects() const;

public slots:
    void setObjects(QList<DocumentObjectMock1 *> objects);

signals:
    void objectsChanged(QList<DocumentObjectMock1 *> objects);

private:
    QList<DocumentObjectMock1 *> m_objects;

    // IDocumentObject interface
public:
    virtual int objectType() const override { return Type; }
};
Q_DECLARE_METATYPE(DocumentObjectMock3*)

class DocumentObjectMock4 : public LDO::IDocumentObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QString> strings READ strings WRITE setStrings NOTIFY stringsChanged)
    Q_PROPERTY(QList<double> doubles READ doubles WRITE setDoubles NOTIFY doublesChanged)
    Q_PROPERTY(QList<QPointF> points READ points WRITE setPoints NOTIFY pointsChanged)
    Q_PROPERTY(QList<QStringList> stringLists READ stringLists WRITE setStringLists NOTIFY stringListsChanged)

public:
    enum
    {
        Type = MockBaseType + 4
    };

    Q_INVOKABLE explicit DocumentObjectMock4();

    QList<QString> strings() const;
    QList<double> doubles() const;
    QList<QPointF> points() const;
    QList<QStringList> stringLists() const;

public slots:
    void setStrings(const QList<QString> &strings);
    void setDoubles(const QList<double> &doubles);
    void setPoints(QList<QPointF> points);
    void setStringLists(QList<QStringList> stringLists);

signals:
    void stringsChanged(QList<QString> &strings);
    void doublesChanged(QList<double> &doubles);
    void pointsChanged(QList<QPointF> points);
    void stringListsChanged(QList<QStringList> stringLists);

private:
    QList<QString> m_strings;
    QList<double> m_doubles;
    QList<QPointF> m_points;
    QList<QStringList> m_stringLists;

    // IDocumentObject interface
public:
    virtual int objectType() const override { return Type; }
};
Q_DECLARE_METATYPE(DocumentObjectMock4*)

#endif // DOCUMENTOBJECTMOCK_H
